home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-03-27 | 36.1 KB | 884 lines | [TEXT/ROSA] |
- Common Lisp the Language, 2nd Edition
- -------------------------------------------------------------------------------
-
- 6. Predicates
-
- A predicate is a function that tests for some condition involving its arguments
- and returns nil if the condition is false, or some non-nil value if the
- condition is true. One may think of a predicate as producing a Boolean value,
- where nil stands for false and anything else stands for true. Conditional
- control structures such as cond, if, when, and unless test such Boolean values.
- We say that a predicate is true when it returns a non-nil value, and is false
- when it returns nil; that is, it is true or false according to whether the
- condition being tested is true or false.
-
- By convention, the names of predicates usually end in the letter p (which
- stands for ``predicate''). Common Lisp uses a uniform convention in hyphenating
- names of predicates. If the name of the predicate is formed by adding a p to an
- existing name, such as the name of a data type, a hyphen is placed before the
- final p if and only if there is a hyphen in the existing name. For example,
- number begets numberp but standard-char begets standard-char-p. On the other
- hand, if the name of a predicate is formed by adding a prefixing qualifier to
- the front of an existing predicate name, the two names are joined with a hyphen
- and the presence or absence of a hyphen before the final p is not changed. For
- example, the predicate string-lessp has no hyphen before the p because it is
- the string version of lessp (a MacLisp function that has been renamed < in
- Common Lisp). The name string-less-p would incorrectly imply that it is a
- predicate that tests for a kind of object called a string-less, and the name
- stringlessp would connote a predicate that tests whether something has no
- strings (is ``stringless'')!
-
- The control structures that test Boolean values only test for whether or not
- the value is nil, which is considered to be false. Any other value is
- considered to be true. Often a predicate will return nil if it ``fails'' and
- some useful value if it ``succeeds''; such a function can be used not only as a
- test but also for the useful value provided in case of success. An example is
- member.
-
- If no better non-nil value is available for the purpose of indicating success,
- by convention the symbol t is used as the ``standard'' true value.
-
- -------------------------------------------------------------------------------
-
- * Logical Values
- * Data Type Predicates
- o General Type Predicates
- o Specific Data Type Predicates
- * Equality Predicates
- * Logical Operators
-
- -------------------------------------------------------------------------------
-
- 6.1. Logical Values
-
- The names nil and t are constants in Common Lisp. Although they are symbols
- like any other symbols, and appear to be treated as variables when evaluated,
- it is not permitted to modify their values. See defconstant.
-
- [Constant]
- nil
-
- The value of nil is always nil. This object represents the logical false value
- and also the empty list. It can also be written ().
-
- [Constant]
- t
-
- The value of t is always t.
-
- -------------------------------------------------------------------------------
-
- 6.2. Data Type Predicates
-
- Perhaps the most important predicates in Lisp are those that deal with data
- types; that is, given a data object one can determine whether or not it belongs
- to a given type, or one can compare two type specifiers.
-
- -------------------------------------------------------------------------------
-
- * General Type Predicates
- * Specific Data Type Predicates
-
- -------------------------------------------------------------------------------
-
- 6.2.1. General Type Predicates
-
- If a data type is viewed as the set of all objects belonging to the type, then
- the typep function is a set membership test, while subtypep is a subset test.
-
- [Function]
- typep object type
-
- typep is a predicate that is true if object is of type type, and is false
- otherwise. Note that an object can be ``of'' more than one type, since one type
- can include another. The type may be any of the type specifiers mentioned in
- chapter 4 except that it may not be or contain a type specifier list whose
- first element is function or values. A specifier of the form (satisfies fn) is
- handled simply by applying the function fn to object (see funcall); the object
- is considered to be of the specified type if the result is not nil.
-
- [change_begin]
- X3J13 voted in January 1989 (ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS) to change
- typep to give specialized array and complex type specifiers the same meaning
- for purposes of type discrimination as they have for declaration purposes. Of
- course, this also applies to such type specifiers as vector and simple-array
- (see section 4.5). Thus
-
- (typep foo '(array bignum))
-
- in the first edition asked the question, Is foo an array specialized to hold
- bignums? but under the new interpretation asks the question, Could the array
- foo have resulted from giving bignum as the :element-type argument to
- make-array?
- [change_end]
-
- [Function]
- subtypep type1 type2
-
- The arguments must be type specifiers that are acceptable to typep. The two
- type specifiers are compared; this predicate is true if type1 is definitely a
- (not necessarily proper) subtype of type2. If the result is nil, however, then
- type1 may or may not be a subtype of type2 (sometimes it is impossible to tell,
- especially when satisfies type specifiers are involved). A second returned
- value indicates the certainty of the result; if it is true, then the first
- value is an accurate indication of the subtype relationship. Thus there are
- three possible result combinations:
-
-
- t t type1 is definitely a subtype of type2
- nil t type1 is definitely not a subtype of type2
- nil nil subtypep could not determine the relationship
-
- [change_begin]
- X3J13 voted in January 1989 (SUBTYPEP-TOO-VAGUE) to place certain
- requirements upon the implementation of subtypep, for it noted that
- implementations in many cases simply ``give up'' and return the two values nil
- and nil when in fact it would have been possible to determine the relationship
- between the given types. The requirements are as follows, where it is
- understood that a type specifier s involves a type specifier u if either s
- contains an occurrence of u directly or s contains a type specifier w defined
- by deftype whose expansion involves u.
-
- * subtypep is not permitted to return a second value of nil unless one or
- both of its arguments involves satisfies, and, or, not, or member.
-
- * subtypep should signal an error when one or both of its arguments
- involves values or the list form of the function type specifier.
-
- * subtypep must always return the two values t and t in the case where its
- arguments, after expansion of specifiers defined by deftype, are equal.
-
- In addition, X3J13 voted to clarify that in some cases the relationships
- between types as reflected by subtypep may be implementation-specific. For
- example, in an implementation supporting only one type of floating-point
- number, (subtypep 'float 'long-float) would return t and t, since the two types
- would be identical.
-
- Note that satisfies is an exception because relationships between types
- involving satisfies are undecidable in general, but (as X3J13 noted) and, or,
- not, and member are merely very messy to deal with. In all likelihood these
- will not be addressed unless and until someone is willing to write a careful
- specification that covers all the cases for the processing of these type
- specifiers by subtypep. The requirements stated above were easy to state and
- probably suffice for most cases of interest.
-
- X3J13 voted in January 1989 (ARRAY-TYPE-ELEMENT-TYPE-SEMANTICS) to change
- subtypep to give specialized array and complex type specifiers the same meaning
- for purposes of type discrimination as they have for declaration purposes. Of
- course, this also applies to such type specifiers as vector and simple-array
- (see section 4.5).
-
- If A and B are type specifiers (other than *, which technically is not a type
- specifier anyway), then (array A) and (array B) represent the same type in a
- given implementation if and only if they denote arrays of the same specialized
- representation in that implementation; otherwise they are disjoint. To put it
- another way, they represent the same type if and only if
- (upgraded-array-element-type 'A) and (upgraded-array-element-type 'B) are the
- same type. Therefore
-
- (subtypep '(array A) '(array B))
-
- is true if and only if (upgraded-array-element-type 'A) is the same type as
- (upgraded-array-element-type 'B).
-
- The complex type specifier is treated in a similar but subtly different manner.
- If A and B are two type specifiers (but not *, which technically is not a type
- specifier anyway), then (complex A) and (complex B) represent the same type in
- a given implementation if and only if they refer to complex numbers of the same
- specialized representation in that implementation; otherwise they are disjoint.
- Note, however, that there is no function called make-complex that allows one to
- specify a particular element type (then to be upgraded); instead, one must
- describe specialized complex numbers in terms of the actual types of the parts
- from which they were constructed. There is no number of type (or rather,
- representation) float as such; there are only numbers of type single-float,
- numbers of type double-float, and so on. Therefore we want (complex
- single-float) to be a subtype of (complex float).
-
- The rule, then, is that (complex A) and (complex B) represent the same type
- (and otherwise are disjoint) in a given implementation if and only if either
- the type A is a subtype of B, or (upgraded-complex-part-type 'A) and
- (upgraded-complex-part-type 'B) are the same type. In the latter case (complex
- A) and (complex B) in fact refer to the same specialized representation.
- Therefore
-
- (subtypep '(complex A) '(complex B))
-
- is true if and only if the results of (upgraded-complex-part-type 'A) and
- (upgraded-complex-part-type 'B) are the same type.
-
- Under this interpretation
-
- (subtypep '(complex single-float) '(complex float))
-
- must be true in all implementations; but
-
- (subtypep '(array single-float) '(array float))
-
- is true only in implementations that do not have a specialized array
- representation for single-float elements distinct from that for float elements
- in general.
- [change_end]
-
- -------------------------------------------------------------------------------
-
- 6.2.2. Specific Data Type Predicates
-
- The following predicates test for individual data types.
-
- [Function]
- null object
-
- null is true if its argument is (), and otherwise is false. This is the same
- operation performed by the function not; however, not is normally used to
- invert a Boolean value, whereas null is normally used to test for an empty
- list. The programmer can therefore express intent by the choice of function
- name.
-
- (null x) == (typep x 'null) == (eq x '())
-
- [Function]
- symbolp object
-
- symbolp is true if its argument is a symbol, and otherwise is false.
-
- (symbolp x) == (typep x 'symbol)
-
- -------------------------------------------------------------------------------
- Compatibility note: The Interlisp equivalent of symbolp is called litatom.
- -------------------------------------------------------------------------------
-
- [Function]
- atom object
-
- The predicate atom is true if its argument is not a cons, and otherwise is
- false. Note that (atom '()) is true, because () nil.
-
- (atom x) == (typep x 'atom) == (not (typep x 'cons))
-
- -------------------------------------------------------------------------------
- Compatibility note: In some Lisp dialects, notably Interlisp, only symbols and
- numbers are considered to be atoms; arrays and strings are considered to be
- neither atoms nor lists (conses).
- -------------------------------------------------------------------------------
-
- [Function]
- consp object
-
- The predicate consp is true if its argument is a cons, and otherwise is false.
- Note that the empty list is not a cons, so (consp '()) == (consp 'nil) => nil.
-
- (consp x) == (typep x 'cons) == (not (typep x 'atom))
-
- -------------------------------------------------------------------------------
- Compatibility note: Some Lisp implementations call this function pairp or
- listp. The name pairp was rejected for Common Lisp because it emphasizes too
- strongly the dotted-pair notion rather than the usual usage of conses in lists.
- On the other hand, listp too strongly implies that the cons is in fact part of
- a list, which after all it might not be; moreover, () is a list, though not a
- cons. The name consp seems to be the appropriate compromise.
- -------------------------------------------------------------------------------
-
- [Function]
- listp object
-
- listp is true if its argument is a cons or the empty list (), and otherwise is
- false. It does not check for whether the list is a ``true list'' (one
- terminated by nil) or a ``dotted list'' (one terminated by a non-null atom).
-
- (listp x) == (typep x 'list) == (typep x '(or cons null))
-
- [Function]
- numberp object
-
- numberp is true if its argument is any kind of number, and otherwise is false.
-
- (numberp x) == (typep x 'number)
-
- [Function]
- integerp object
-
- integerp is true if its argument is an integer, and otherwise is false.
-
- (integerp x) == (typep x 'integer)
-
- -------------------------------------------------------------------------------
- Compatibility note: In MacLisp this is called fixp. Users have been confused as
- to whether this meant integerp or fixnump, and so the name integerp has been
- adopted here.
- -------------------------------------------------------------------------------
-
- [Function]
- rationalp object
-
- rationalp is true if its argument is a rational number (a ratio or an integer),
- and otherwise is false.
-
- (rationalp x) == (typep x 'rational)
-
- [Function]
- floatp object
-
- floatp is true if its argument is a floating-point number, and otherwise is
- false.
-
- (floatp x) == (typep x 'float)
-
- [change_begin]
-
- [Function]
- realp object
-
- X3J13 voted in March 1989 (REAL-NUMBER-TYPE) to add the function realp. realp
- is true if its argument is a real number, and otherwise is false.
-
- (realp x) == (typep x 'real)
-
- [change_end]
-
- [Function]
- complexp object
-
- complexp is true if its argument is a complex number, and otherwise is false.
-
- (complexp x) == (typep x 'complex)
-
- [Function]
- characterp object
-
- characterp is true if its argument is a character, and otherwise is false.
-
- (characterp x) == (typep x 'character)
-
- [Function]
- stringp object
-
- stringp is true if its argument is a string, and otherwise is false.
-
- (stringp x) == (typep x 'string)
-
- [Function]
- bit-vector-p object
-
- bit-vector-p is true if its argument is a bit-vector, and otherwise is false.
-
- (bit-vector-p x) == (typep x 'bit-vector)
-
- [Function]
- vectorp object
-
- vectorp is true if its argument is a vector, and otherwise is false.
-
- (vectorp x) == (typep x 'vector)
-
- [Function]
- simple-vector-p object
-
- vectorp is true if its argument is a simple general vector, and otherwise is
- false.
-
- (simple-vector-p x) == (typep x 'simple-vector)
-
- [Function]
- simple-string-p object
-
- simple-string-p is true if its argument is a simple string, and otherwise is
- false.
-
- (simple-string-p x) == (typep x 'simple-string)
-
- [Function]
- simple-bit-vector-p object
-
- simple-bit-vector-p is true if its argument is a simple bit-vector, and
- otherwise is false.
-
- (simple-bit-vector-p x) == (typep x 'simple-bit-vector)
-
- [Function]
- arrayp object
-
- arrayp is true if its argument is an array, and otherwise is false.
-
- (arrayp x) == (typep x 'array)
-
- [Function]
- packagep object
-
- packagep is true if its argument is a package, and otherwise is false.
-
- (packagep x) == (typep x 'package)
-
- [Function]
- functionp object
-
- [old_change_begin]
- functionp is true if its argument is suitable for applying to arguments, using
- for example the funcall or apply function. Otherwise functionp is false.
-
- functionp is always true of symbols, lists whose car is the symbol lambda, any
- value returned by the function special form, and any values returned by the
- function compile when the first argument is nil.
- [old_change_end]
-
- [change_begin]
- X3J13 voted in June 1988 (FUNCTION-TYPE) to define
-
- (functionp x) == (typep x 'function)
-
- Because the vote also specifies that types cons and symbol are disjoint from
- the type function, this is an incompatible change; now functionp is in fact
- always false of symbols and lists.
- [change_end]
-
- [Function]
- compiled-function-p object
-
- compiled-function-p is true if its argument is any compiled code object, and
- otherwise is false.
-
- (compiled-function-p x) == (typep x 'compiled-function)
-
- [old_change_begin]
- [Function]
- commonp object
-
- commonp is true if its argument is any standard Common Lisp data type, and
- otherwise is false.
-
- (commonp x) == (typep x 'common)
-
- [old_change_end]
-
- [change_begin]
- X3J13 voted in March 1989 (COMMON-TYPE) to remove the predicate commonp (and
- the type common) from the language.
- [change_end]
-
- See also standard-char-p, string-char-p, streamp, random-state-p, readtablep,
- hash-table-p, and pathnamep.
-
- -------------------------------------------------------------------------------
-
- 6.3. Equality Predicates
-
- Common Lisp provides a spectrum of predicates for testing for equality of two
- objects: eq (the most specific), eql, equal, and equalp (the most general). eq
- and equal have the meanings traditional in Lisp. eql was added because it is
- frequently needed, and equalp was added primarily in order to have a version of
- equal that would ignore type differences when comparing numbers and case
- differences when comparing characters. If two objects satisfy any one of these
- equality predicates, then they also satisfy all those that are more general.
-
- [Function]
- eq x y
-
- (eq x y) is true if and only if x and y are the same identical object.
- (Implementationally, x and y are usually eq if and only if they address the
- same identical memory location.)
-
- It should be noted that things that print the same are not necessarily eq to
- each other. Symbols with the same print name usually are eq to each other
- because of the use of the intern function. However, numbers with the same value
- need not be eq, and two similar lists are usually not eq. For example:
-
- (eq 'a 'b) is false.
- (eq 'a 'a) is true.
- (eq 3 3) might be true or false, depending on the implementation.
- (eq 3 3.0) is false.
- (eq 3.0 3.0) might be true or false, depending on the implementation.
- (eq #c(3 -4) #c(3 -4))
- might be true or false, depending on the implementation.
- (eq #c(3 -4.0) #c(3 -4)) is false.
- (eq (cons 'a 'b) (cons 'a 'c)) is false.
- (eq (cons 'a 'b) (cons 'a 'b)) is false.
- (eq '(a . b) '(a . b)) might be true or false.
- (progn (setq x (cons 'a 'b)) (eq x x)) is true.
- (progn (setq x '(a . b)) (eq x x)) is true.
- (eq #\A #\A) might be true or false, depending on the implementation.
- (eq "Foo" "Foo") might be true or false.
- (eq "Foo" (copy-seq "Foo")) is false.
- (eq "FOO" "foo") is false.
-
- In Common Lisp, unlike some other Lisp dialects, the implementation is
- permitted to make ``copies'' of characters and numbers at any time. (This
- permission is granted because it allows tremendous performance improvements in
- many common situations.) The net effect is that Common Lisp makes no guarantee
- that eq will be true even when both its arguments are ``the same thing'' if
- that thing is a character or number. For example:
-
- (let ((x 5)) (eq x x)) might be true or false.
-
- The predicate eql is the same as eq, except that if the arguments are
- characters or numbers of the same type then their values are compared. Thus eql
- tells whether two objects are conceptually the same, whereas eq tells whether
- two objects are implementationally identical. It is for this reason that eql,
- not eq, is the default comparison predicate for the sequence functions defined
- in chapter 14.
-
- -------------------------------------------------------------------------------
- Implementation note: eq simply compares the two given pointers, so any kind of
- object that is represented in an ``immediate'' fashion will indeed have
- like-valued instances satisfy eq. In some implementations, for example, fixnums
- and characters happen to ``work.'' However, no program should depend on this,
- as other implementations of Common Lisp might not use an immediate
- representation for these data types.
- -------------------------------------------------------------------------------
-
- [old_change_begin]
- An additional problem with eq is that the implementation is permitted to
- ``collapse'' constants (or portions thereof) appearing in code to be compiled
- if they are equal. An object is considered to be a constant in code to be
- compiled if it is a self-evaluating form or is contained in a quote form. This
- is why (eq "Foo" "Foo") might be true or false; in interpreted code it would
- normally be false, because reading in the form (eq "Foo" "Foo") would construct
- distinct strings for the two arguments to eq, but the compiler might choose to
- use the same identical string or two distinct copies as the two arguments in
- the call to eq. Similarly, (eq '(a . b) '(a . b)) might be true or false,
- depending on whether the constant conses appearing in the quote forms were
- collapsed by the compiler. However, (eq (cons 'a 'b) (cons 'a 'b)) is always
- false, because every distinct call to the cons function necessarily produces a
- new and distinct cons.
- [old_change_end]
-
- [change_begin]
- X3J13 voted in March 1989 (QUOTE-SEMANTICS) to clarify that eval and compile
- are not permitted either to copy or to coalesce (``collapse'') constants (see
- eq) appearing in the code they process; the resulting program behavior must
- refer to objects that are eql to the corresponding objects in the source code.
- Only the compile-file/load process is permitted to copy or coalesce constants
- (see section 25.1).
- [change_end]
-
- [Function]
- eql x y
-
- The eql predicate is true if its arguments are eq, or if they are numbers of
- the same type with the same value, or if they are character objects that
- represent the same character. For example:
-
- (eql 'a 'b) is false.
- (eql 'a 'a) is true.
- (eql 3 3) is true.
- (eql 3 3.0) is false.
- (eql 3.0 3.0) is true.
- (eql #c(3 -4) #c(3 -4)) is true.
- (eql #c(3 -4.0) #c(3 -4)) is false.
- (eql (cons 'a 'b) (cons 'a 'c)) is false.
- (eql (cons 'a 'b) (cons 'a 'b)) is false.
- (eql '(a . b) '(a . b)) might be true or false.
- (progn (setq x (cons 'a 'b)) (eql x x)) is true.
- (progn (setq x '(a . b)) (eql x x)) is true.
- (eql #\A #\A) is true.
- (eql "Foo" "Foo") might be true or false.
- (eql "Foo" (copy-seq "Foo")) is false.
- (eql "FOO" "foo") is false.
-
- Normally (eql 1.0s0 1.0d0) would be false, under the assumption that 1.0s0 and
- 1.0d0 are of distinct data types. However, implementations that do not provide
- four distinct floating-point formats are permitted to ``collapse'' the four
- formats into some smaller number of them; in such an implementation (eql 1.0s0
- 1.0d0) might be true. The predicate = will compare the values of two numbers
- even if the numbers are of different types.
-
- If an implementation supports positive and negative zeros as distinct values
- (as in the IEEE proposed standard floating-point format), then (eql 0.0 -0.0)
- will be false. Otherwise, when the syntax -0.0 is read it will be interpreted
- as the value 0.0, and so (eql 0.0 -0.0) will be true. The predicate = differs
- from eql in that (= 0.0 -0.0) will always be true, because = compares the
- mathematical values of its operands, whereas eql compares the representational
- values, so to speak.
-
- Two complex numbers are considered to be eql if their real parts are eql and
- their imaginary parts are eql. For example, (eql #C(4 5) #C(4 5)) is true and
- (eql #C(4 5) #C(4.0 5.0)) is false. Note that while (eql #C(5.0 0.0) 5.0) is
- false, (eql #C(5 0) 5) is true. In the case of (eql #C(5.0 0.0) 5.0) the two
- arguments are of different types and so cannot satisfy eql; that's all there is
- to it. In the case of (eql #C(5 0) 5), however, #C(5 0) is not a complex number
- but is always automatically reduced by the rule of complex canonicalization to
- the integer 5, just as the apparent ratio 20/4 is always simplified to 5.
-
- The case of (eql "Foo" "Foo") is discussed above in the description of eq.
- While eql compares the values of numbers and characters, it does not compare
- the contents of strings. To compare the characters of two strings, one should
- use equal, equalp, string=, or string-equal.
-
- -------------------------------------------------------------------------------
- Compatibility note: The Common Lisp function eql is similar to the Interlisp
- function eqp. However, eql considers 3 and 3.0 to be different, whereas eqp
- considers them to be the same; eqp behaves like the Common Lisp = function, not
- like eql, when both arguments are numbers.
- -------------------------------------------------------------------------------
-
- [Function]
- equal x y
-
- The equal predicate is true if its arguments are structurally similar
- (isomorphic) objects. A rough rule of thumb is that two objects are equal if
- and only if their printed representations are the same.
-
- Numbers and characters are compared as for eql. Symbols are compared as for eq.
- This method of comparing symbols can violate the rule of thumb for equal and
- printed representations, but only in the infrequently occurring case of two
- distinct symbols with the same print name.
-
- Certain objects that have components are equal if they are of the same type and
- corresponding components are equal. This test is implemented in a recursive
- manner and may fail to terminate for circular structures.
-
- For conses, equal is defined recursively as the two car's being equal and the
- two cdr's being equal.
-
- Two arrays are equal only if they are eq, with one exception: strings and
- bit-vectors are compared element-by-element. If either argument has a fill
- pointer, the fill pointer limits the number of elements examined by equal.
- Uppercase and lowercase letters in strings are considered by equal to be
- distinct. (In contrast, equalp ignores case distinctions in strings.)
-
- -------------------------------------------------------------------------------
- Compatibility note: In Lisp Machine Lisp, equal ignores the difference between
- uppercase and lowercase letters in strings. This violates the rule of thumb
- about printed representations, however, which is very useful, especially to
- novices. It is also inconsistent with the treatment of single characters, which
- in Lisp Machine Lisp are represented as fixnums.
- -------------------------------------------------------------------------------
-
- Two pathname objects are equal if and only if all the corresponding components
- (host, device, and so on) are equivalent. (Whether or not uppercase and
- lowercase letters are considered equivalent in strings appearing in components
- depends on the file name conventions of the file system.) Pathnames that are
- equal should be functionally equivalent.
-
- [change_begin]
- X3J13 voted in June 1989 (EQUAL-STRUCTURE) to clarify that equal never
- recursively descends any structure or data type other than the ones explicitly
- described above: conses, bit-vectors, strings, and pathnames. Numbers and
- characters are compared as if by eql, and all other data objects are compared
- as if by eq.
- [change_end]
-
- (equal 'a 'b) is false.
- (equal 'a 'a) is true.
- (equal 3 3) is true.
- (equal 3 3.0) is false.
- (equal 3.0 3.0) is true.
- (equal #c(3 -4) #c(3 -4)) is true.
- (equal #c(3 -4.0) #c(3 -4)) is false.
- (equal (cons 'a 'b) (cons 'a 'c)) is false.
- (equal (cons 'a 'b) (cons 'a 'b)) is true.
- (equal '(a . b) '(a . b)) is true.
- (progn (setq x (cons 'a 'b)) (equal x x)) is true.
- (progn (setq x '(a . b)) (equal x x)) is true.
- (equal #\A #\A) is true.
- (equal "Foo" "Foo") is true.
- (equal "Foo" (copy-seq "Foo")) is true.
- (equal "FOO" "foo") is false.
-
- To compare a tree of conses using eql (or any other desired predicate) on the
- leaves, use tree-equal.
-
- [Function]
- equalp x y
-
- Two objects are equalp if they are equal; if they are characters and satisfy
- char-equal, which ignores alphabetic case and certain other attributes of
- characters; if they are numbers and have the same numerical value, even if they
- are of different types; or if they have components that are all equalp.
-
- Objects that have components are equalp if they are of the same type and
- corresponding components are equalp. This test is implemented in a recursive
- manner and may fail to terminate for circular structures. For conses, equalp is
- defined recursively as the two car's being equalp and the two cdr's being
- equalp.
-
- Two arrays are equalp if and only if they have the same number of dimensions,
- the dimensions match, and the corresponding components are equalp. The
- specializations need not match; for example, a string and a general array that
- happens to contain the same characters will be equalp (though definitely not
- equal). If either argument has a fill pointer, the fill pointer limits the
- number of elements examined by equalp. Because equalp performs
- element-by-element comparisons of strings and ignores the alphabetic case of
- characters, case distinctions are therefore also ignored when equalp compares
- strings.
-
- Two symbols can be equalp only if they are eq, that is, the same identical
- object.
-
- [change_begin]
- X3J13 voted in June 1989 (EQUAL-STRUCTURE) to specify that equalp compares
- components of hash tables (see below), and to clarify that otherwise equalp
- never recursively descends any structure or data type other than the ones
- explicitly described above: conses, arrays (including bit-vectors and strings),
- and pathnames. Numbers are compared for numerical equality (see =), characters
- are compared as if by char-equal, and all other data objects are compared as if
- by eq.
-
- Two hash tables are considered the same by equalp if and only if they satisfy a
- four-part test:
-
- * They must be of the same kind; that is, equivalent :test arguments were
- given to make-hash-table when the two hash tables were created.
-
- * They must have the same number of entries (see hash-table-count).
-
- * For every entry (key1, value1) in one hash table there must be a
- corresponding entry (key2, value2) in the other, such that key1 and key2
- are considered to be the same by the :test function associated with the
- hash tables.
-
- * For every entry (key1, value1) in one hash table and its corresponding
- entry (key2, value2) in the other, such that key1 and key2 are the same,
- equalp must be true of value1 and value2.
-
- The four parts of this test are carried out in the order shown, and if some
- part of the test fails, equalp returns nil and the other parts of the test are
- not attempted.
-
- If equalp must compare two structures and the defstruct definition for one used
- the :type option and the other did not, then equalp returns nil.
-
- If equalp must compare two structures and neither defstruct definition used the
- :type option, then equalp returns t if and only if the structures have the same
- type (that is, the same defstruct name) and the values of all corresponding
- slots (slots having the same name) are equalp.
-
- As part of the X3J13 discussion of this issue the following observations were
- made. Object equality is not a concept for which there is a uniquely determined
- correct algorithm. The appropriateness of an equality predicate can be judged
- only in the context of the needs of some particular program. Although these
- functions take any type of argument and their names sound very generic, equal
- and equalp are not appropriate for every application. Any decision to use or
- not use them should be determined by what they are documented to do rather than
- by any abstract characterization of their function. If neither equal nor equalp
- is found to be appropriate in a particular situation, programmers are
- encouraged to create another operator that is appropriate rather than blame
- equal or equalp for ``doing the wrong thing.''
-
- Note that one consequence of the vote to change the rules of floating-point
- contagion (CONTAGION-ON-NUMERICAL-COMPARISONS) (described in section 12.1) is
- to make equalp a true equivalence relation on numbers.
- [change_end]
-
- (equalp 'a 'b) is false.
- (equalp 'a 'a) is true.
- (equalp 3 3) is true.
- (equalp 3 3.0) is true.
- (equalp 3.0 3.0) is true.
- (equalp #c(3 -4) #c(3 -4)) is true.
- (equalp #c(3 -4.0) #c(3 -4)) is true.
- (equalp (cons 'a 'b) (cons 'a 'c)) is false.
- (equalp (cons 'a 'b) (cons 'a 'b)) is true.
- (equalp '(a . b) '(a . b)) is true.
- (progn (setq x (cons 'a 'b)) (equalp x x)) is true.
- (progn (setq x '(a . b)) (equalp x x)) is true.
- (equalp #\A #\A) is true.
- (equalp "Foo" "Foo") is true.
- (equalp "Foo" (copy-seq "Foo")) is true.
- (equalp "FOO" "foo") is true.
-
- -------------------------------------------------------------------------------
-
- 6.4. Logical Operators
-
- Common Lisp provides three operators on Boolean values: and, or, and not. Of
- these, and and or are also control structures because their arguments are
- evaluated conditionally. The function not necessarily examines its single
- argument, and so is a simple function.
-
- [Function]
- not x
-
- not returns t if x is nil, and otherwise returns nil. It therefore inverts its
- argument considered as a Boolean value.
-
- null is the same as not; both functions are included for the sake of clarity.
- As a matter of style, it is customary to use null to check whether something is
- the empty list and to use not to invert the sense of a logical value.
-
- [Macro]
- and {form}*
-
- (and form1 form2 ... ) evaluates each form, one at a time, from left to right.
- If any form evaluates to nil, the value nil is immediately returned without
- evaluating the remaining forms. If every form but the last evaluates to a
- non-nil value, and returns whatever the last form returns. Therefore in general
- and can be used both for logical operations, where nil stands for false and
- non-nil values stand for true, and as a conditional expression. An example
- follows.
-
- (if (and (>= n 0)
- (< n (length a-simple-vector))
- (eq (elt a-simple-vector n) 'foo))
- (princ "Foo!"))
-
- The above expression prints Foo! if element n of a-simple-vector is the symbol
- foo, provided also that n is indeed a valid index for a-simple-vector. Because
- and guarantees left-to-right testing of its parts, elt is not called if n is
- out of range.
-
- To put it another way, the and special form does short-circuit Boolean
- evaluation, like the and then operator in Ada and what in some Pascal-like
- languages is called cand (for ``conditional and''); the Lisp and special form
- is unlike the Pascal or Ada and operator, which always evaluates both
- arguments.
-
- In the previous example writing
-
- (and (>= n 0)
- (< n (length a-simple-vector))
- (eq (elt a-simple-vector n) 'foo)
- (princ "Foo!"))
-
- would accomplish the same thing. The difference is purely stylistic. Some
- programmers never use expressions containing side effects within and,
- preferring to use if or when for that purpose.
-
- From the general definition, one can deduce that (and x) == x. Also, (and)
- evaluates to t, which is an identity for this operation.
-
- One can define and in terms of cond in this way:
-
- (and x y z ... w) == (cond ((not x) nil)
- ((not y) nil)
- ((not z) nil)
- ...
- (t w))
-
- See if and when, which are sometimes stylistically more appropriate than and
- for conditional purposes. If it is necessary to test whether a predicate is
- true of all elements of a list or vector (element 0 and element 1 and element 2
- and ...), then the function every may be useful.
-
- [Macro]
- or {form}*
-
- (or form1 form2 ... ) evaluates each form, one at a time, from left to right.
- If any form other than the last evaluates to something other than nil, or
- immediately returns that non-nil value without evaluating the remaining forms.
- If every form but the last evaluates to nil, or returns whatever evaluation of
- the last of the forms returns. Therefore in general or can be used both for
- logical operations, where nil stands for false and non-nil values stand for
- true, and as a conditional expression.
-
- To put it another way, the or special form does short-circuit Boolean
- evaluation, like the or else operator in Ada and what in some Pascal-like
- languages is called cor (for ``conditional or''); the Lisp or special form is
- unlike the Pascal or Ada or operator, which always evaluates both arguments.
-
- From the general definition, one can deduce that (or x) == x. Also, (or)
- evaluates to nil, which is the identity for this operation.
-
- One can define or in terms of cond in this way:
-
- (or x y z ... w) == (cond (x) (y) (z) ... (t w))
-
- See if and unless, which are sometimes stylistically more appropriate than or
- for conditional purposes. If it is necessary to test whether a predicate is
- true of one or more elements of a list or vector (element 0 or element 1 or
- element 2 or ...), then the function some may be useful.
-
- -------------------------------------------------------------------------------
-
-
-
-
-